#pragma once 
#include <iostream>
#include <string>
#include <time.h>
#include <jsoncpp/json/json.h>
#include <atomic>
#include <random>
#include <sstream>
#include <iomanip>
#include <chrono>


enum{
    DEBUG,
    INFO,
    ERROR
};

std::string gettime()
{
    time_t t = time(nullptr);
    struct tm* lt = localtime(&t);
    char buffer[1024];
    sprintf(buffer, "%d-%d-%d-%d:%d:%d", lt->tm_year+1900, lt->tm_mon+1,
    lt->tm_mday, lt->tm_hour, lt->tm_min, lt->tm_sec);
    return buffer;
}


inline std::ostream& log(const std::string& level, const std::string& file, int line)
{
    std::string message = "[";
    message += level;
    message += "]";

    message += "[";
    message += file;
    message += "]";

    message += "[";
    message += std::to_string(line);
    message += "]";

    message += "[";
    message += gettime();
    message += "]";
    message += " ";

    std::cout << message;
    return std::cout;
}

#define LOG(level) log(#level, __FILE__, __LINE__)

class JSON
{
public:
    static bool serialize(const Json::Value &val,  std::string &body) {
        std::stringstream ss;
        //先实例化一个工厂类对象
        Json::StreamWriterBuilder swb;
        //通过工厂类对象来生产派生类对象
        std::unique_ptr<Json::StreamWriter> sw(swb.newStreamWriter());
        int ret = sw->write(val, &ss);
        if (ret != 0) {
            LOG(ERROR) << "序列化失败" << "\n";
            return false;
        }
        body = ss.str();
        return true;
    }

    static bool unserialize(const std::string &body, Json::Value &val) {
        Json::CharReaderBuilder crb;
        std::string errs;
        std::unique_ptr<Json::CharReader> cr(crb.newCharReader());
        bool ret = cr->parse(body.c_str(), body.c_str() + body.size(), &val, &errs);
        if (ret == false) {
            LOG(ERROR) << "反序列化失败, " << errs.c_str() << "\n";
            return false;
        }
        return true;
    }
};

class UUID
{
public:
    static std::string uuid()
    {
        std::stringstream ss;
        // 构造随机数对象
        std::random_device rd;
        // 构造伪随机数对象
        std::mt19937_64 generator(rd());
        // 构造限定数据范围的对象
        std::uniform_int_distribution<int> distribution(0, 255);
        // 生成8个随机数，按照特定格式组织为16进制数字字符的字符串
        for(int i=0; i<8; i++)
        {
            if(i == 4 || i == 6) ss << "-"; 
            ss << std::setw(2) << std::setfill('0') << std::hex << distribution(generator);
        }
        ss << "-";
        // 定义8字节序号，按照特定格式组织为16进制数字字符的字符串
        static std::atomic<size_t> seq(1);
        size_t cur = seq.fetch_add(1);
        for(int i=7; i>=0; i--)
        {
            if(i == 5) ss << "-";
            ss << std::setw(2) << std::setfill('0') << (cur >> (i*8) & 0xFF);
        }
        return ss.str();
    }
};